package com.dff.jrfw;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.PopupWindow;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.biometric.BiometricManager;
import androidx.biometric.BiometricPrompt;
import androidx.databinding.DataBindingUtil;

import com.dff.jrfw.common.Constant;
import com.dff.jrfw.databinding.ActivityFingerLoginBinding;
import com.dff.jrfw.dialog.BiometricIdentifyDialog;
import com.dff.jrfw.model.LoginModel;
import com.dff.jrfw.model.QueryDeviceInfoModel;
import com.dff.jrfw.model.TokenBodyModel;
import com.dff.jrfw.model.TokenUserNameModel;
import com.dff.jrfw.remote.CustomCallBack;
import com.dff.jrfw.remote.RetrofitUtils;
import com.dff.jrfw.remote.RetrofitUtilsTwo;
import com.dff.jrfw.requestBody.LoginDto;
import com.dff.jrfw.service.WebPreloadService;
import com.dff.jrfw.utils.CertUtils;
import com.dff.jrfw.utils.DeviceIdUtil;
import com.dff.jrfw.utils.GsonUtils;
import com.dff.jrfw.utils.SharedPreferenceUtils;
import com.dff.jrfw.utils.ToastUtil;
import com.dff.jrfw.utils.Util;
import com.dff.jrfw.utils.XORUtils;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.Executor;

import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Response;

public class FingerLoginActivity extends BaseActivity implements View.OnClickListener {

    private ActivityFingerLoginBinding binding;
    private String username;

    public static void callMe(Context context, String username) {
        Intent intent = new Intent(context, FingerLoginActivity.class);
        intent.putExtra("username", username);
        context.startActivity(intent);
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_finger_login);
        username = getIntent().getStringExtra("username");
        initView();
    }


    private void initView() {
        binding.layoutBack.setOnClickListener(this);
        binding.tvMore.setOnClickListener(this);
        binding.ivFinger.setOnClickListener(this);
    }


    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.layout_back:
                finish();
                break;
            case R.id.iv_finger:
                queryDeviceInfo(username);
                break;
            case R.id.tv_more:
                initPop();
                break;
        }
    }


    private void initPop() {
        View popView = LayoutInflater.from(FingerLoginActivity.this).inflate(R.layout.pop_other_login_type_layout, null);
        final PopupWindow popupWindow = new PopupWindow(popView, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
        popView.findViewById(R.id.tv_finger_login).setVisibility(View.GONE);
        popView.findViewById(R.id.view_line_finger).setVisibility(View.GONE);
        popView.findViewById(R.id.tv_cancel).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                popupWindow.dismiss();
            }
        });
        popView.findViewById(R.id.tv_psd_login).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                popupWindow.dismiss();
                PsdLoginActivity.callMe(FingerLoginActivity.this, username);
            }
        });


        //设置SelectPicPopupWindow弹出窗体可点击
        popupWindow.setFocusable(true);
        popupWindow.setOutsideTouchable(true);
        // 实例化一个ColorDrawable颜色为半透明
        ColorDrawable dw = new ColorDrawable(getResources().getColor(R.color.transparent_background_25));
        // 设置PickPopupWindow弹出窗体的背景
        popupWindow.setBackgroundDrawable(dw);
        popupWindow.setClippingEnabled(false);
        popupWindow.setAnimationStyle(R.style.PopupAnimaFade);
        popupWindow.showAtLocation(popView, Gravity.BOTTOM, 0, 0);
    }

    public enum Stage {
        FINGERPRINT,
        NEW_FINGERPRINT_ENROLLED,
        PASSWORD
    }


    private void doLogin(LoginDto loginDto) {
        showLoading();
        RetrofitUtils.getService().doLogin("1", "1", loginDto).enqueue(new CustomCallBack<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                hideLoading();
                try {
                    if (response.body() != null) {
                        String result = response.body().string();
                        JSONObject jsonObject = new JSONObject(result);
                        int code = jsonObject.getInt("code");
                        if (code == 200) {
                            JSONObject data = jsonObject.getJSONObject("data");
                            LoginModel loginModel = GsonUtils.gsonToBean(data.toString(), LoginModel.class);
                            SharedPreferenceUtils.getInstance().put(FingerLoginActivity.this, Constant.TOKEN, Util.capitalize(loginModel.getTokenType()) + " " + loginModel.getAccessToken());
                            SharedPreferenceUtils.getInstance().put(FingerLoginActivity.this, Constant.CURRENT_LOGIN_ACCOUNT, loginDto.getUsername());
                            try {
                                String bodyStr = XORUtils.jwtDecoded(loginModel.getAccessToken());
                                TokenBodyModel tokenBodyModel = GsonUtils.gsonToBean(bodyStr, TokenBodyModel.class);
                                String userName = tokenBodyModel.getUserName();
                                TokenUserNameModel tokenUserNameModel = GsonUtils.gsonToBean(userName, TokenUserNameModel.class);
                                Integer firstEnter = tokenUserNameModel.getFirstEnter();
                                if (firstEnter == 1 || firstEnter == 2) {
                                    SetNewLoginPsdActivity.callMe(FingerLoginActivity.this, loginDto.getUsername());
                                } else {
                                    SharedPreferenceUtils.getInstance().saveAccount(FingerLoginActivity.this, username);
                                    MainActivity.callMe(FingerLoginActivity.this);
                                    finish();
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        } else if (code == 906) {
                            ToastUtil.toast("用户名或密码错误");
                        } else {
                            String msg = jsonObject.getString("msg");
                            ToastUtil.toast(msg);
                        }
                    } else {
                        ResponseBody errorResponseBody = response.errorBody();
                        if (errorResponseBody != null) {
                            ToastUtil.toast(errorResponseBody.string());
                        }
                    }
                } catch (IOException | JSONException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(Call call, Throwable t) {
                super.onFailure(call, t);
                hideLoading();
            }
        });
    }


    @RequiresApi(api = Build.VERSION_CODES.M)
    private void queryDeviceInfo(String username) {
        showLoading();
        RetrofitUtilsTwo.getService().doAccountIsAlive("1", "1", username).enqueue(new CustomCallBack<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                try {
                    if (response.body() != null) {
                        String result = response.body().string();
                        JSONObject jsonObject = new JSONObject(result);
                        int code = jsonObject.getInt("code");
                        if (code == 200) {
                            JSONObject data = jsonObject.optJSONObject("data");
                            String muDevices = data.optString("muDevices");
                            boolean isEnable = false;
                            if (!"null".equals(muDevices) && !TextUtils.isEmpty(muDevices)) {
                                List<QueryDeviceInfoModel.MuDevicesDTO> muDevicesDTOS = GsonUtils.jsonToList(muDevices, QueryDeviceInfoModel.MuDevicesDTO.class);
                                if (!muDevicesDTOS.isEmpty()) {
                                    String deviceId = DeviceIdUtil.getDeviceId(FingerLoginActivity.this);
                                    for (int i = 0; i < muDevicesDTOS.size(); i++) {
                                        if (muDevicesDTOS.get(i).getDeviceId().equals(deviceId)) {
                                            if (muDevicesDTOS.get(i).getFpSwitch() == 1) {
                                                //指纹开关启用
                                                isEnable = true;
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                            if (isEnable) {
//                                doBio2();
                                doBio();
                            } else {
                                hideLoading();
                                FingerSetActivity.callMe(FingerLoginActivity.this, username, false);
                            }
                        } else {
                            hideLoading();
                            String msg = jsonObject.getString("msg");
                            ToastUtil.toast(msg);
                        }
                    } else {
                        hideLoading();
                        ResponseBody errorResponseBody = response.errorBody();
                        if (errorResponseBody != null) {
                            ToastUtil.toast(errorResponseBody.string());
                        }
                    }
                } catch (IOException | JSONException e) {
                    hideLoading();
                    e.printStackTrace();
                }

            }

            @Override
            public void onFailure(Call call, Throwable t) {
                super.onFailure(call, t);
                hideLoading();
            }
        });
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    private void doBio() {
        new BiometricIdentifyDialog(this, new BiometricIdentifyDialog.CallBack() {
            @Override
            public void success() {
                SharedPreferenceUtils.getInstance().put(FingerLoginActivity.this, Constant.TOKEN, "Basic TlNUQ0FQUDphbXR1V0d0SVFtSlZkMW8wWW04eU1VMTZVVlExZHowOQ==");
                LoginDto loginDto = new LoginDto();
                loginDto.setUsername(username);
                loginDto.setGrantType("finger");
                loginDto.setPassword(DeviceIdUtil.getDeviceId(FingerLoginActivity.this));


                String certDn = CertUtils.getCertDn(FingerLoginActivity.this, username);
                loginDto.setCertDn(certDn);
                String PIN = (String) SharedPreferenceUtils.getInstance().get(FingerLoginActivity.this, username, "");
                if (!TextUtils.isEmpty(PIN)) {
                    CertUtils.sign(FingerLoginActivity.this, 1, username, PIN, username + "+" + certDn, new CertUtils.OnSignCallBackListener() {
                        @Override
                        public void onSignCallBack(String sign) {
                            if (!TextUtils.isEmpty(sign)) {
                                loginDto.setSign(sign);
                                doLogin(loginDto);
                            }
                        }
                    });
                }
            }

            @Override
            public void onPrepared() {
                hideLoading();
            }

            @Override
            public void failure(String msg) {
                ToastUtil.toast(msg);
            }
        }).show();
    }

    private boolean isBiometricEnable() {
        BiometricManager biometricManager = BiometricManager.from(this);
        switch (biometricManager.canAuthenticate()) {
            case BiometricManager.BIOMETRIC_SUCCESS:
                return true;
            case BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE:
                ToastUtil.toast("该设备上没有搭载可用的生物特征功能");
                return false;
            case BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE:
                ToastUtil.toast("生物识别功能当前不可用");
//                Settings.ACTION_SECURITY_SETTINGS
                return false;
            case BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED:
                ToastUtil.toast("您还没有录入生物识别数据");
                return false;
            default:
                return false;
        }
    }

    private Handler handler = new Handler();
    private Executor executor = new Executor() {
        @Override
        public void execute(Runnable command) {
            handler.post(command);
        }
    };

    private void doBio2() {
        if(isBiometricEnable()){
            BiometricPrompt.PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder()
                    .setTitle("您正在使用生物识别进行登录")
                    .setAllowedAuthenticators(BiometricManager.Authenticators.BIOMETRIC_WEAK)
                    .setNegativeButtonText("使用其它方式")
                    .setConfirmationRequired(true)
                    .build();
            BiometricPrompt biometricPrompt = new BiometricPrompt(FingerLoginActivity.this,
                    executor, new BiometricPrompt.AuthenticationCallback() {
                //各种异常的回调
                @Override
                public void onAuthenticationError(int errorCode,
                                                  @NonNull CharSequence errString) {
                    super.onAuthenticationError(errorCode, errString);
                    ToastUtil.toast("认证失败:" + errString);
                    hideLoading();
                }

                //认证成功的回调
                @Override
                public void onAuthenticationSucceeded(
                        @NonNull BiometricPrompt.AuthenticationResult result) {
                    super.onAuthenticationSucceeded(result);
                    Log.d("xxx", "认证成功");
                    SharedPreferenceUtils.getInstance().put(FingerLoginActivity.this, Constant.TOKEN, "Basic TlNUQ0FQUDphbXR1V0d0SVFtSlZkMW8wWW04eU1VMTZVVlExZHowOQ==");
                    LoginDto loginDto = new LoginDto();
                    loginDto.setUsername(username);
                    loginDto.setGrantType("finger");
                    loginDto.setPassword(DeviceIdUtil.getDeviceId(FingerLoginActivity.this));


                    String certDn = CertUtils.getCertDn(FingerLoginActivity.this, username);
                    loginDto.setCertDn(certDn);
                    String PIN = (String) SharedPreferenceUtils.getInstance().get(FingerLoginActivity.this, username, "");
                    if (!TextUtils.isEmpty(PIN)) {
                        CertUtils.sign(FingerLoginActivity.this, 1, username, PIN, username + "+" + certDn, new CertUtils.OnSignCallBackListener() {
                            @Override
                            public void onSignCallBack(String sign) {
                                if (!TextUtils.isEmpty(sign)) {
                                    loginDto.setSign(sign);
                                    doLogin(loginDto);
                                }
                            }
                        });
                    }
                }

                //认证失败的回调
                @Override
                public void onAuthenticationFailed() {
                    super.onAuthenticationFailed();
                    ToastUtil.toast("认证失败");
                }
            });
            // 显示认证对话框
            biometricPrompt.authenticate(promptInfo);
        }else {
            hideLoading();
        }
    }
}